<template>
  <a-space direction="vertical">
    <a-card>
      <a-form
        ref="searchRef"
        name="searchBar"
        :model="searchFormState"
        :labelCol="{ span: 5, offset: 1 }"
        @finish="handleSearch"
      >
        <a-row :gutter="24">
          <a-col :span="8">
            <a-form-item name="roleId" label="角色ID">
              <a-input
                v-model:value="searchFormState[`roleId`]"
                placeholder=""
              ></a-input>
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item name="roleCode" label="角色码">
              <a-input
                v-model:value="searchFormState[`roleCode`]"
                placeholder=""
              ></a-input>
            </a-form-item>
          </a-col>
          <a-col :span="8">
            <a-form-item name="roleName" label="角色名">
              <a-input
                v-model:value="searchFormState[`roleName`]"
                placeholder=""
              ></a-input>
            </a-form-item>
          </a-col>
        </a-row>
        <a-row>
          <a-col :span="24" style="text-align: right">
            <a-button type="primary" html-type="submit" :loading="searchLoading"
              >搜索</a-button
            >
            <a-button
              style="margin: 0 8px"
              @click="() => searchRef?.resetFields()"
              >重置</a-button
            >
          </a-col>
        </a-row>
      </a-form>
    </a-card>
    <a-card>
      <a-space>
        <a-button @click="showModal"
          ><template #icon> <appstore-add-outlined /> </template>新增</a-button
        >
        <a-button @click="showEditModal"
          ><template #icon> <form-outlined /> </template>修改</a-button
        >
        <a-button @click="handleDel" danger
          ><template #icon> <delete-outlined /> </template>删除</a-button
        >
      </a-space>
    </a-card>
    <a-card title="查询结果">
      <a-table
        class="ant-table-striped"
        :rowClassName="
          (_record, index) => (index % 2 === 1 ? 'table-striped' : null)
        "
        :columns="columns"
        :data-source="data"
        rowKey="roleId"
        :loading="searchLoading"
        :rowSelection="rowSelection"
        @change="
                    (pagination: any) => {
                        handleSearch(pagination);
                    }
                "
        :pagination="{
          position: [`bottomRight`],
          showSizeChanger: true,
          showQuickJumper: true,
          current: pageIndex,
          pageSize,
          showTotal: (total) => `总计 ${total} 条记录`,
        }"
      >
        <template #bodyCell="{ column, text }">
          <template v-if="column.dataIndex === 'name'">
            <a>{{ text }}</a>
          </template>
        </template>
      </a-table>
    </a-card>

    <a-modal
      ref="modalRef"
      v-model:visible="visible"
      :wrap-style="{ overflow: 'hidden' }"
      @ok="handleOk"
    >
      <template #title>
        <div ref="modalTitleRef" style="width: 100%; cursor: move">
          {{ currentAction }}角色权限配置
        </div>
      </template>
      <template #modalRender="{ originVNode }">
        <div :style="transformStyle">
          <component :is="originVNode" />
        </div>
      </template>

      <a-form
        ref="formRef"
        :model="formState"
        layout="vertical"
        name="form_in_modal"
      >
        <a-form-item
          name="roleName"
          label="角色名"
          :rules="[{ required: true, message: '请输入角色名' }]"
        >
          <a-input v-model:value="formState.roleName" />
        </a-form-item>
        <a-form-item
          name="roleCode"
          label="角色码"
          :rules="[{ required: true, message: '请输入角色码' }]"
        >
          <a-input v-model:value="formState.roleCode" />
        </a-form-item>
        <a-form-item
          name="roleDesc"
          label="角色描述"
          :rules="[{ required: true, message: '请输入角色描述' }]"
        >
          <a-input v-model:value="formState.roleDesc" />
        </a-form-item>
      </a-form>
    </a-modal>
  </a-space>
</template>
<script lang="ts" setup>
// base library
import { LISTHEADER } from "./config";
import { roldQuery, roleAdd, roleUpdate, roleDel } from "@/api/base";
import { onMounted } from "@vue/runtime-core";
import {
  computed,
  createVNode,
  CSSProperties,
  reactive,
  ref,
  toRaw,
  unref,
  watch,
  watchEffect,
} from "vue";
import { FormInstance, message, Modal } from "ant-design-vue";
import { useDraggable } from "@vueuse/core";
import { ExclamationCircleOutlined } from "@ant-design/icons-vue";

const searchRef = ref<FormInstance>();
let searchLoading = ref(true);
const searchFormState: { [propName: string]: any } = reactive({});

const columns = LISTHEADER;
let pageIndex = ref(1);
let pageSize = ref(10);
let total = ref(0);
let data = ref([]);
const handleSearch = (values: any) => {
  searchLoading.value = true;
  console.log("Received values of form: ", values);
  console.log("searchFormState: ", searchFormState);
  let parameter = { ...searchFormState };
  if (values?.current) {
    // 分页切换
    pageIndex.value = values?.current;
    pageSize.value = values?.pageSize;
  } else {
    // 搜索
    selectedRowKeys.value = [];
    selectedRows.value = [];
    pageIndex.value = 1;
  }
  const requestParameters = Object.assign({}, parameter, {
    pageIndex: pageIndex.value,
    pageSize: pageSize.value,
  });
  console.log("loadData request parameters:", requestParameters);

  roldQuery(requestParameters).then(
    (res: {
      code: number | string;
      msg: string;
      total: number;
      datas: any;
    }) => {
      searchLoading.value = false;
      const { code, msg, total: count, datas } = res;
      if (code === "777") {
        data.value = datas;
        total.value = count;
      } else {
        total.value = 0;
        data.value = [];
        pageIndex.value = 1;
        message.error(msg);
      }
    }
  );
};

const selectedRowKeys = ref<string[]>([]); // Check here to configure the default column
const selectedRows = ref<T[]>([]);
const onSelectChange = (changableRowKeys: string[], changableRows: T[]) => {
  console.log("selectedRowKeys changed: ", changableRowKeys);
  selectedRowKeys.value =
    changableRowKeys.length > 1 ? [changableRowKeys.pop()] : changableRowKeys;
  selectedRows.value =
    changableRows.length > 1 ? [changableRows.pop()] : changableRows;
};
const rowSelection = computed(() => {
  return {
    selectedRowKeys: unref(selectedRowKeys),
    onChange: onSelectChange,
    hideDefaultSelections: true,
  };
});

enum action {
  add = "新增",
  edit = "编辑",
}
const currentAction = ref(action.add);
const visible = ref<boolean>(false);
const modalTitleRef = ref<HTMLElement>(null);
const showModal = () => {
  visible.value = true;
  currentAction.value = action.add;
};
const { x, y, isDragging } = useDraggable(modalTitleRef);
const startX = ref<number>(0);
const startY = ref<number>(0);
const startedDrag = ref(false);
const transformX = ref(0);
const transformY = ref(0);
const preTransformX = ref(0);
const preTransformY = ref(0);
const dragRect = ref({ left: 0, right: 0, top: 0, bottom: 0 });
watch([x, y], () => {
  if (!startedDrag.value) {
    startX.value = x.value;
    startY.value = y.value;
    const bodyRect = document.body.getBoundingClientRect();
    const titleRect = modalTitleRef.value.getBoundingClientRect();
    dragRect.value.right = bodyRect.width - titleRect.width;
    dragRect.value.bottom = bodyRect.height - titleRect.height;
    preTransformX.value = transformX.value;
    preTransformY.value = transformY.value;
  }
  startedDrag.value = true;
});
watch(isDragging, () => {
  if (!isDragging) {
    startedDrag.value = false;
  }
});
watchEffect(() => {
  if (startedDrag.value) {
    transformX.value =
      preTransformX.value +
      Math.min(Math.max(dragRect.value.left, x.value), dragRect.value.right) -
      startX.value;
    transformY.value =
      preTransformY.value +
      Math.min(Math.max(dragRect.value.top, y.value), dragRect.value.bottom) -
      startY.value;
  }
});
const transformStyle = computed<CSSProperties>(() => {
  return {
    transform: `translate(${transformX.value}px, ${transformY.value}px)`,
  };
});

interface FormValues {
  roleCode: string;
  roleName: string;
  roleDesc: string;
}
const formRef = ref<FormInstance>();
const formState = reactive<FormValues>({
  roleCode: "",
  roleName: "",
  roleDesc: "",
});
const showEditModal = () => {
  if (selectedRowKeys.value.length > 1)
    message.error("仅能选择一条记录进行操作");
  if (selectedRowKeys.value.length === 0)
    message.error("请选择一条记录进行操作");
  if (selectedRowKeys.value.length === 1) {
    currentAction.value = action.edit;
    visible.value = true;
    formState.roleCode = selectedRows.value[0].roleCode;
    formState.roleName = selectedRows.value[0].roleName;
    formState.roleDesc = selectedRows.value[0].roleDesc;
  }
};
const handleOk = (e: MouseEvent) => {
  console.log(e);
  visible.value = false;

  formRef.value
    .validateFields()
    .then((values) => {
      console.log("Received values of form: ", values);
      console.log("formState: ", toRaw(formState));
      visible.value = false;

      if (currentAction.value === action.add) {
        roleAdd(formState).then((res) => {
          const { code, msg } = res;
          if (code === "777") {
            Modal.success({
              title: msg,
            });
            formRef.value.resetFields();
            console.log("reset formState: ", toRaw(formState));
          } else {
            Modal.error({
              title: msg,
            });
          }
        });
      }
      if (currentAction.value === action.edit) {
        roleUpdate(formState).then((res) => {
          const { code, msg } = res;
          if (code === "777") {
            Modal.success({
              title: msg,
            });
            formRef.value.resetFields();
            console.log("reset formState: ", toRaw(formState));
          } else {
            Modal.error({
              title: msg,
            });
          }
        });
      }
    })
    .catch((info) => {
      console.log("Validate Failed:", info);
    });
};
const handleDel = () => {
  if (selectedRowKeys.value.length > 1)
    message.error("仅能选择一条记录进行操作");
  if (selectedRowKeys.value.length === 0)
    message.error("请选择一条记录进行操作");
  if (selectedRowKeys.value.length === 1) {
    Modal.confirm({
      title: "请确认是否操作删除?",
      icon: createVNode(ExclamationCircleOutlined),
      okText: "删除",
      okType: "danger",
      cancelText: "取消",
      onOk() {
        console.log("selectedRows: ", toRaw(selectedRows.value[0]));
        roleDel(selectedRows.value[0]).then((res) => {
          const { code, msg } = res;
          if (code === "777") {
            console.log("resp: ", toRaw(res));
            Modal.success({
              title: msg,
            });
          } else {
            Modal.error({
              title: msg,
            });
          }
        });
      },
      onCancel() {
        console.log("Cancel");
      },
    });
  }
};

onMounted(() => {
  searchLoading.value = false;
});
</script>
<script lang="ts">
import {
  AppstoreAddOutlined,
  FormOutlined,
  DeleteOutlined,
} from "@ant-design/icons-vue";
export default {
  name: "BasicPage",
  components: {
    AppstoreAddOutlined,
    FormOutlined,
    DeleteOutlined,
  },
};
</script>
<style type="less" scoped>
.ant-table-striped :deep(.table-striped) td {
  background-color: #fafafa;
}
</style>
